﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Reflection;

using ESRI.ArcGIS.Client.Geometry;

using TouchToolkit.Framework;
using TouchToolkit.Framework.TouchInputProviders;
using TouchToolkit.GestureProcessor.Feedbacks.TouchFeedbacks;
using TouchToolkit.GestureProcessor.ReturnTypes;
using TouchToolkit.GestureProcessor.Gesture_Definitions;

namespace GISforTT_API
{
    /// <summary>
    /// This class represents the background map of the application
    /// It also uses the TouchInputProvider
    /// </summary>
    public partial class GisInterfaceMgr : UserControl
    {
        TouchInputProvider touchProvider;
        Window mainWindow;

        BookmarkList bookmarklist = null;
        MapFrameFactory mapframefact = null;
        BackgroundMapLayer backgroundLayer = null;
        CornerMenusMgr cornermenusmgr = null;
        Orientation MapOrientation = Orientation.Horizontal;
        bool allowBgManip = false;

        #region Interface Configurations
        
        // Type of corner menus
        CornerMenusMgr.CornerMenuType cornerMenuType = CornerMenusMgr.CornerMenuType.NoCornerMenus;

        // Background map extent
        Envelope BackgroundMapExtent = null;

        List<MapLayerDef> defaultLayerTypes = null;
        
        List<Bookmark> bookmarks = null;
        
        #endregion

        /// <summary>
        /// Returns the Instance of the GisInterfaceMgr singleton class
        /// </summary>
        public static GisInterfaceMgr Instance { get; private set; }

        static GisInterfaceMgr() { Instance = new GisInterfaceMgr(); }

        // Private Constructor
        GisInterfaceMgr()
        {
            InitializeComponent();

            LayoutRoot.Height = System.Windows.SystemParameters.VirtualScreenHeight;
            LayoutRoot.Width = System.Windows.SystemParameters.VirtualScreenWidth;

            touchProvider = new Windows7TouchInputProvider();

            this.Loaded += new RoutedEventHandler(GisInterfaceMgr_Loaded);
        }

        
        private void GisInterfaceMgr_Loaded(object sender, RoutedEventArgs e)
        {
            // Configure Gesture Toolkit
            GestureFramework.Initialize(touchProvider, LayoutRoot, Assembly.GetExecutingAssembly());
            //GestureFramework.ShowDebugPanel(GestureFramework.DebugPanels.GestureRecorder);
            GestureFramework.AddTouchFeedback(typeof(BubblesPath));
            //This feedback allows the user to see which area has been selected by the gesture
            //GestureFramework.AddGesturFeedback(Gestures.Lasso, typeof(TouchToolkit.GestureProcessor.Feedbacks.GestureFeedbacks.HighlightSelectedArea));
            GestureFramework.EventManager.BubbleUpUnhandledEvents = true;
            
            
            // Initialize the mapLayersManager
            MapLayersManager layersMgr = MapLayersManager.Instance;            
            layersMgr.setDefaultLayerTypes(defaultLayerTypes);
            layersMgr.InitializeDefaultMapLayers();

            bookmarklist = BookmarkList.Instance;
            bookmarklist.initializeBookmarkList(bookmarks);

            mapframefact = MapFrameFactory.Instance;

            // Create the instance of the Background map layer
            backgroundLayer = BackgroundMapLayer.Instance;
            backgroundLayer.setLayoutProperties(LayoutRoot.Width, LayoutRoot.Height, MapOrientation);            
            backgroundLayer.allowManipulationOfBgMap(allowBgManip);
            // Called last to put the properties in effect
            backgroundLayer.InitializeBackgroundMap(BackgroundMapExtent);
                        
            cornermenusmgr = CornerMenusMgr.Instance;
            cornermenusmgr.setLayoutRoot(LayoutRoot);
            cornermenusmgr.MenuType = cornerMenuType;
            cornermenusmgr.CreateCornerMenus();
            cornermenusmgr.CreateExitDialogs();

            LayoutRoot.Children.Add(backgroundLayer);                                    
        }

        
        #region Interface Configurations

        /// <summary>
        /// You can use Orientation.Horizontal or Orientation.Vertical. This will change the orientation of the background map with respect to the screen/table.
        /// </summary>
        /// <param name="or">Orientation of the application</param>
        public void setOrientation(Orientation or)
        {
            MapOrientation = or;
        }

        /// <summary>
        /// Sets the type of the corner menus
        /// </summary>
        /// <param name="menuType"></param>
        public void setCornerMenusType(CornerMenusMgr.CornerMenuType menuType)
        {
            cornerMenuType = menuType;
        }

        /// <summary>
        /// To specify the location coordinates shown on the background map, you can use this method which takes as arguments the longitude and latitude coordinates of the extent/rectangle. 
        /// </summary>
        /// <param name="minX">minimum x location (latitude)</param>
        /// <param name="minY">minimum y location (longitude)</param>
        /// <param name="maxX">maximum x location</param>
        /// <param name="maxY">maximum y location</param>
        public void setBackgroundMapLocation(double minX, double minY, double maxX, double maxY)
        {
            Envelope extent = new Envelope(minX, minY, maxX, maxY);

            BackgroundMapExtent = extent;
        }

        /// <summary>
        /// Sets the default map layers of the application
        /// </summary>
        /// <param name="layerTypes">List of map layer types</param>
        public void setDefaultMapLayerTypes(List<MapLayerDef> layerTypes)
        {
            defaultLayerTypes = layerTypes;
        }

        
        /// <summary>
        /// Sets the list of bookmarks to be created on the background map
        /// </summary>
        /// <param name="bkmks">List of bookmarks</param>
        public void setBookmarkList(List<Bookmark> bkmks)
        {
            bookmarks = bkmks;                        
        }

        /// <summary>
        /// Gets the list of bookmarks to be created on the background map
        /// </summary>
        public List<Bookmark> getBookmarkList()
        {
            return bookmarks;
        }

        
        /// <summary>
        /// enables/disables the manipulation of the background map (panning and zooming)
        /// </summary>
        /// <param name="allowPanZoom">True to allow panning and zooming</param>
        public void allowManipulationOfBackgroundMap(bool allowPanZoom)
        {
            allowBgManip = allowPanZoom;
        }

        #endregion

        /// <summary>
        /// Returns the Touch Input Provider
        /// </summary>
        /// <returns></returns>
        public TouchInputProvider getTouchInputProvider()
        {
            return touchProvider;
        }

        /// <summary>
        /// Sets the main window of the application
        /// </summary>
        /// <param name="mw"></param>
        public void setMainWindow(Window mw)
        {
            mainWindow = mw;
        }

        /// <summary>
        /// Returns the main window of the application.
        /// </summary>
        /// <returns></returns>
        public Window getMainWindow()
        {
            return mainWindow;
        }
        
    }
}
